#ifndef _BINARYOPERATION_
#define _BINARYOPERATION_

#include "Expression.h"
#include "BinaryOperationType.h"
#include "../ExpressionValue.h"

struct BinaryOperation: public Expression
{
public:
    BinaryOperation(BinaryOperationType iOperation, TreeNode* iLeft, TreeNode* iRight);
    virtual ~BinaryOperation();
    virtual void CheckVariables(set<string>& oVariables, string iParentName);
    virtual void CheckFunctionCalls(set<FunctionDefinition*>& iAllFunctions, string iParentName);
    virtual void CheckClassConstructions(set<ClassDefinition*>& iAllClasses, string iParentName);
    virtual void CheckExpressionTypes(map<string, ExpressionType*>& iVarTypes, string iParentName);
    virtual ExpressionType* GetType(map<string, ExpressionType*>& iVarTypes, string iParentName);
    virtual void Accept(GeneralVisitor* iVisitor);

    static bool AreTypesOK(ValueType iLeftType, ValueType iRightType, BinaryOperationType iOp);
    static ExpressionValue* EvaluateNumericExpression(long iVal1, long iVal2, BinaryOperationType iOp);
    static ExpressionValue* EvaluateNumericExpression(long iVal1, double iVal2, BinaryOperationType iOp);
    static ExpressionValue* EvaluateNumericExpression(double iVal1, long iVal2, BinaryOperationType iOp);
    static ExpressionValue* EvaluateNumericExpression(double iVal1, double iVal2, BinaryOperationType iOp);
    static ExpressionValue* EvaluateStringExpression(string iVal1, string iVal2, BinaryOperationType iOp);
    static ExpressionValue* EvaluateBoolExpression(bool iVal1, bool iVal2, BinaryOperationType iOp);

    BinaryOperationType GetOperation()  { return fOperation;    }
    TreeNode*           GetLeft()       { return fLeft;         }
    TreeNode*           GetRight()      { return fRight;        }

private:
    BinaryOperationType fOperation;
    TreeNode* fLeft;
    TreeNode* fRight;
};

#endif
